#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/select.h>
#include <map>
#include <stdlib.h>
#include <dirent.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>

using namespace std;


bool dfs(const char*, int print(const char* name, const struct stat* st), int);

char buffer[1000000];


int print(const char* name, const struct stat* st) {
    cout << name << endl;
    return 0;
}

int main(int argc, char* argv[]) {
    if(argc < 2) {
      cout << "Something goes wrong" << endl;
      exit(-1);
    } else {
      exit(dfs(argv[1], print, 1));
    }
}

bool dfs(const char* dirname, int print(const char* name, const struct stat* st), int do_dirs) {
    DIR* dir = opendir(dirname);
    struct stat stat;
    struct dirent* dirent;
    bool check = false;
    size_t len = strlen(dirname);
    if(dir != NULL) {
    strncpy(buffer, dirname, len);
    while((dirent = readdir(dir)) != NULL) {
    std::string name = dirent -> d_name;
    if(strcmp(name.c_str(), ".") == 0 ||
       strcmp(name.c_str(), "..") == 0) {
        continue;
    }

    buffer[len] = '/';
    buffer[len+1] = '\0';
    strcat(buffer, name.c_str());
    if(lstat(buffer, &stat) == -1)  {
        perror(name.c_str());
        check = true;
        break;
    }

    if(S_ISDIR(stat.st_mode)) {
        if(do_dirs && print(buffer, &stat)) {
            check = true;
            break;
        } else {
            if(dfs(buffer, print, do_dirs)) {
              check = true;
              break;
            }
        }
    }
    else {
        if(print(name.c_str(), &stat)) {
          check = true;
          break;
        }
    }
    buffer[len] = '\0';
    }
    closedir(dir);
    return check;
    } else {
        perror(dirname);
        return true;
     }
}




